package com.novelastudios.collections
{
	import com.novelastudios.events.ListIndexEvent;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import org.casalib.collection.List;
	
	
	[Event(name="index_change",type="com.novelastudios.events.ListIndexEvent")]
	
	/**
	 *	@example The following code sets the volume level for your sound:
	 * 	<listing version="3.0">
	 * 
	 * 		var list:SelectableList = new SelectableList(["a","b","c","d","e","g","h"]);
	 * 		list.addEventListener(ListIndexEvent.INDEX_CHANGE,handleIndexChanges);
	 * 		list.nextIndex();
	 * 
	 * 		function handleIndexChanges( event:ListIndexEvent ):void
	 * 		{
	 * 			trace( list.selectedIndex ); // outputs 1
	 * 			trace( event.oldIndex ); // outputs 0
	 * 			trace( event.data ); // outputs "b"
	 * 		}
	 * </listing>
	 * 
	 * @author Rockfish Interactive ©2010
	 */
	public class SelectableList extends List implements IEventDispatcher
	{
		public function SelectableList(collection:Array=null)
		{
			super(collection);
			dispatcher = new EventDispatcher(this);
		}
		//////////////////////////////////////////////////////////////////////////////////////////////////
		//										PROPERTIES
		//////////////////////////////////////////////////////////////////////////////////////////////////
		
		//////////////////////////////////////////////////////////////////////////////////////////////////
		//										ACCESSORS
		//////////////////////////////////////////////////////////////////////////////////////////////////
		
		///////////////////////////////
		//-------------------------
		//	selectedIndex
		//-------------------------
		private var _selectedIndex:int = 0;
		
		public function get selectedIndex():int
		{
			return _selectedIndex;
		}
		
		public function set selectedIndex(value:int):void
		{
			if(_selectedIndex == value)
				return;
			
			var oldIndex:int = selectedIndex;
			
			if(!loopIndexChanges)
				_selectedIndex = Math.max(0,Math.min(value,size-1));
			else
			{
				if(value >= size)
					_selectedIndex = 0;
				else if(value < 0)
					_selectedIndex = size-1;
				else
					_selectedIndex = value;
			}
			
			
			dispatchEvent(new ListIndexEvent(ListIndexEvent.INDEX_CHANGE,oldIndex,_selectedIndex,getItemAt(_selectedIndex)));
		}
		
		///////////////////////////////
		//-------------------------
		//	loopIndexChanges
		//-------------------------
		private var _loopIndexChanges:Boolean;
		
		public function get loopIndexChanges():Boolean
		{
			return _loopIndexChanges;
		}
		
		public function set loopIndexChanges(value:Boolean):void
		{
			_loopIndexChanges = value;
		}
		
		///////////////////////////////
		//-------------------------
		//	dispatcher
		//-------------------------
		private var _dispatcher:EventDispatcher;
		
		public function get dispatcher():EventDispatcher
		{
			return _dispatcher;
		}
		
		public function set dispatcher(value:EventDispatcher):void
		{
			_dispatcher = value;
		}
		
		
		//////////////////////////////////////////////////////////////////////////////////////////////////
		//										PUBLIC METHODS
		//////////////////////////////////////////////////////////////////////////////////////////////////
		public function nextIndex():void
		{
			selectedIndex = selectedIndex + 1;
		}
		
		public function previousIndex():void
		{
			selectedIndex = selectedIndex - 1;
		}
		
		
		/**
		 * @inheritDoc
		 */
		public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
		{
			dispatcher.addEventListener(type,listener,useCapture,priority,useWeakReference);
		}
		
		/**
		 * @inheritDoc
		 */
		public function dispatchEvent(event:Event):Boolean
		{
			return dispatcher.dispatchEvent(event);
		}
		
		/**
		 * @inheritDoc
		 */
		public function hasEventListener(type:String):Boolean
		{
			return dispatcher.hasEventListener(type);
		}
		
		/**
		 * @inheritDoc
		 */
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
		{
			return dispatcher.removeEventListener(type,listener,useCapture);
		}
		
		/**
		 * @inheritDoc
		 */
		public function willTrigger(type:String):Boolean
		{
			return dispatcher.willTrigger(type);
		}
		
		
	}
}